package com.ls.rbac.service.impl;
import com.ls.rbac.entity.Dept;
import com.ls.rbac.entity.User;
import com.ls.rbac.entity.UserRole;
import com.ls.rbac.mapper.UserMapper;
import com.ls.rbac.service.IDeptService;
import com.ls.rbac.service.IUserRoleService;
import com.ls.rbac.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;

import java.util.List;
import java.util.stream.Collectors;
/**
 * @author liusheng
 * @since 2025--06--28
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Resource
    private IUserRoleService userRoleService;

    @Resource
    private IDeptService deptService;


    @Override
    public User getUserByUsername(String username) {
        if (StringUtils.isBlank(username)) {
            return null;
        }
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername, username);
        queryWrapper.eq(User::getIsEnabled, (byte) 1);
        User user = this.getOne(queryWrapper);
        return user;
    }

    @Override
    public IPage<User> pageUsersByDeptId(Page<User> page, User user, Integer deptId) {
        if (deptId == null) {
            return getUsersByCondition(page, user);
        }
        List<Integer> deptIds = deptService.getDeptAndChildrenIds(deptId);
        LambdaQueryWrapper<User> queryWrapper = createBaseQueryWrapper(user);
        queryWrapper.in(User::getDeptId, deptIds);
        return this.page(page, queryWrapper);
    }

    private IPage<User> getUsersByCondition(Page<User> page, User user) {
        LambdaQueryWrapper<User> queryWrapper = createBaseQueryWrapper(user);
        return this.page(page, queryWrapper);
    }

    private LambdaQueryWrapper<User> createBaseQueryWrapper(User user) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getDeleted, (byte) 0);
        // 添加查询条件
        if (user != null) {
            if (StringUtils.isNotBlank(user.getUsername())) {
                queryWrapper.like(User::getUsername, user.getUsername());
            }
            if (StringUtils.isNotBlank(user.getRealname())) {
                queryWrapper.like(User::getRealname, user.getRealname());
            }
            if (StringUtils.isNotBlank(user.getPhone())) {
                queryWrapper.like(User::getPhone, user.getPhone());
            }
            if (user.getGender() != null) {
                queryWrapper.eq(User::getGender, user.getGender());
            }
            if (user.getIsEnabled() != null) {
                queryWrapper.eq(User::getIsEnabled, user.getIsEnabled());
            }
        }
        return queryWrapper;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addUser(User user, List<Integer> roleIds) {
        PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(15);
        user.setPassword("{bcrypt}" + passwordEncoder.encode(user.getPassword()));
        user.setIsAccountNonExpired((byte) 1);
        user.setIsAccountNonLocked((byte) 1);
        user.setIsCredentialsNonExpired((byte) 1);
        user.setDeleted((byte) 0);
        Dept byId = deptService.getById(user.getDeptId());
        if (byId == null) {
            throw new RuntimeException("部门不存在");
        }
        user.setDeptName(byId.getDeptName());
        // 保存用户
        boolean saved = this.save(user);
        if (saved && roleIds != null && !roleIds.isEmpty()) {
            saveUserRoles(user.getId(), roleIds);
        }
        return saved;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateUser(User user, List<Integer> roleIds) {
        PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(15);
        if (StringUtils.isNotBlank(user.getPassword())) {
            user.setPassword("{bcrypt}" + passwordEncoder.encode(user.getPassword()));
        } else {
            user.setPassword(null);
        }
        boolean updated = this.updateById(user);
        if (updated && roleIds != null) {
            LambdaQueryWrapper<UserRole> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(UserRole::getUserId, user.getId());
            userRoleService.remove(wrapper);
            if (!roleIds.isEmpty()) {
                saveUserRoles(user.getId(), roleIds);
            }
        }
        return updated;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteUser(Integer userId) {
        LambdaQueryWrapper<UserRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserRole::getUserId, userId);
        try {
            userRoleService.remove(wrapper);
        } catch (Exception e) {
            throw new RuntimeException("删除用户关联失败");
        }
        return this.removeById(userId);
    }

    @Override
    public String resetPassword(Integer userId) {
        String newPassword = "123@reset." + LocalDateTime.now().getYear();
        User user = new User();
        user.setId(userId);
        PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(15);
        user.setPassword("{bcrypt}" + passwordEncoder.encode(newPassword));
        this.updateById(user);
        System.out.println("重置密码为: " + newPassword);
        return newPassword;
    }


    private void saveUserRoles(Integer userId, List<Integer> roleIds) {
        List<UserRole> userRoles = roleIds.stream()
                .map(roleId -> new UserRole().setUserId(userId).setRoleId(roleId))
                .collect(Collectors.toList());
        userRoleService.saveBatch(userRoles);
    }


    public void assignRolesToUser(Integer userId, List<Integer> roleIds) {
        if (userId == null || roleIds == null || roleIds.isEmpty()) {
            throw new IllegalArgumentException("用户ID和角色ID列表不能为空");
        }
        try {
            LambdaQueryWrapper<UserRole> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(UserRole::getUserId, userId);
            userRoleService.remove(queryWrapper);
            saveUserRoles(userId, roleIds);
        } catch (Exception e) {
            throw new RuntimeException("删除用户角色关联失败：" + e.getMessage());
        }
    }

    @Override
    public List<User> pageUsersByDeptId(Integer deptId) {
        if (deptId == null) {
            return List.of();
        }
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getDeptId, deptId);
        return this.list(queryWrapper);
    }


}
